<template>
  <div class="container">
    <el-upload
      ref="upload"
      :action="action"
      :on-preview="handlePreview1"
      :on-progress="onProgress"
      :on-remove="handleRemove"
      :http-request="uploadOss"
      :on-success="onSuccess"
      :on-exceed="onExceed"
      :on-change="onChange"
      :on-error="onError"
      :before-upload="beforeUpload"
      :headers="headers"
      :limit="limit"
      :file-list="files"
      :list-type="listType"
    >
      <div class="uploadTip">
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">{{ tip }}</div>
      </div>
    </el-upload>
    <span v-if="statusInfo !== ''" style="color:#F56C6C">{{ statusInfo }}</span>
    <el-dialog
      :visible.sync="uploadFileVisible"
      top="15vh"
      width="415px"
      :append-to-body="true"
    >
      <img v-if="preViewFileType === 'image'" width="100%" :src="path" alt="" style="box-shadow: 0 0 5px #888">
      <video v-if="preViewFileType === 'video'" :src="path" width="100%" controls="controls">
        您的浏览器不支持html5视频播放
      </video>
    </el-dialog>
  </div>
</template>

<script>
import Cookie from 'js-cookie'
import {TokenType} from '@/utils/enum'
import Message from '@/utils/message'
import compress from '@/utils/compress'

export default {
  props: {
    action: {
      type: String,
      default: process.env.VUE_APP_BASE_API + '/files'
    },
    limit: {
      type: Number,
      default: 1
    },
    fileType: {
      type: Array,
      default: () => ['image']
    },
    tip: {
      type: String,
      default: ''
    },
    fileList: {
      type: [Array, String],
      default: () => []
    },
    objKey: {
      type: String,
      default: ''
    },
    listType: {
      type: String,
      default: 'picture'
    },
    multifile: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      headers: {
        Authorization: 'Bearer ' + Cookie.get(TokenType.USER_TOKEN)
      },
      image: ['image/jpeg', 'image/png', 'image/gif'],
      video: ['video/mp4'],
      path: '',
      uploadFileVisible: false,
      preViewFileType: '',
      statusInfo: '',
      imageType: ['jpg', 'jpeg', 'png', 'gif'],
      videoType: ['mp4'],
      file: null
    }
  },
  computed: {
    files: function () {
      let fileList
      if (typeof this.fileList === 'string') {
        if (this.fileList !== '') {
          if (!this.multifile) {
            return [{name: this.fileList, url: this.fileList}]
          }
          fileList = this.fileList.split(',')
        } else {
          return []
        }
      }
      if (Array.isArray(this.fileList)) {
        fileList = JSON.parse(JSON.stringify(this.fileList))
      }
      const arr = []
      for (const item of fileList) {
        arr.push({
          name: item,
          url: item
        })
      }
      return arr
    }
  },
  watch: {
    fileList: function (val) {
      this.statusInfo = ''
    }
  },
  methods: {
    handleRemove(file, fileList) {
      this.file = null
      this.statusInfo = ''
      this.$emit('handleRemove', {key: this.objKey, response: file.url || file.response})
    },
    handlePreview(file) {
      if (file.status === 'uploading') {
        return
      }
      if (file.status === 'success') {
        if (file.raw) {
          this.preViewFileType = file.raw.type.split('/')[0]
          this.path = file.response
        } else {
          const fileType = file.url.slice(file.url.lastIndexOf('.') + 1)
          if (this.imageType.includes(fileType)) {
            this.preViewFileType = 'image'
          } else if (this.videoType.includes(fileType)) {
            this.preViewFileType = 'video'
          } else {
            return
          }
          this.path = file.url
        }
        this.uploadFileVisible = true
      }
    },
    handlePreview1(file) {
      if (file.status === 'uploading') {
        return
      }
      if (file.status === 'success') {
        if (this.fileType.includes('image')) {
          this.preViewFileType = 'image'
        } else {
          this.preViewFileType = 'video'
        }
        this.path = file.url
        this.uploadFileVisible = true
      }
    },
    async beforeUpload(file) {
      if (!Cookie.get(TokenType.USER_TOKEN) && !Cookie.get(TokenType.USER_REFRESHTOKEN)) {
        this.$store.dispatch('user/fedLogOut')
        return Promise.reject()
      }
      if (!Cookie.get(TokenType.USER_TOKEN) && Cookie.get(TokenType.USER_REFRESHTOKEN)) {
        await this.$store.dispatch('user/reFresh')
        this.$set(this.header, 'Authorization', 'Bearer ' + Cookie.get(TokenType.USER_TOKEN))
      }
      if (!this.validateFileType(file)) {
        return Promise.reject()
      }
      if (file.type.split('/')[0] === 'image') { // 图片
        if (file.size > 1024 * 1024 * 20) {
          Message({
            type: 'error',
            message: '抱歉,上传的图片过大'
          })
          return Promise.reject()
        }
        if (file.size > 1024 * 1024 * 2) {
          return new Promise(async resolve => {
            const res = await compress(file)
            this.file = file
            resolve(res)
          })
        }
      }
      if (file.type.split('/')[0] === 'video') { // 视频
        if (file.size > 1024 * 1024 * 10) {
          Message({
            type: 'error',
            message: '抱歉,上传的视频过大'
          })
          return Promise.reject()
        }
        return Promise.resolve(file)
      }
    },
    onChange(file, fileList) {

    },
    onProgress(event, file, fileList) {
      this.statusInfo = '文件上传中...'
    },
    onSuccess(response, file, fileList) {
      this.statusInfo = '上传成功'
      this.$emit('onSuccess', {key: this.objKey, response})
    },
    // eslint-disable-next-line handle-callback-err
    onError(err, file, fileList) {
      this.statusInfo = '文件上传失败'
    },
    onExceed(files, fileList) {
      Message({
        type: 'error',
        message: `最多只能上传${this.limit}个,请先删除`
      })
    },
    validateFileType(file) {
      const type = file.type.split('/')[0]
      if (!this.fileType.includes(type)) {
        Message({
          type: 'error',
          message: '不支持的格式'
        })
        return false
      }
      if (!this[type].includes(file.type)) {
        Message({
          type: 'error',
          message: `不支持的${type}格式`
        })
        return false
      }
      return true
    }
  }
}
</script>
<style lang="scss" scoped>
.container {
  // max-width: 519px;
  padding: 0;
}

/deep/ .el-upload-list__item { //去掉上传组件动画
  transition: none !important;
}

.uploadTip {
  display: flex;

  .el-upload__tip {
    margin: 0 20px;
    line-height: 30px;
  }
}
</style>
